home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / Snippets / Printing / Print multipage PICT / print.p < prev    next >
Encoding:
Text File  |  1994-02-24  |  9.5 KB  |  307 lines  |  [TEXT/PJMM]

  1. {    This file has been processed by The THINK Pascal Source Converter, v1.1.2.    }
  2.  
  3. {    This file has been processed by The THINK Pascal Source Converter, v1.1.2.    }
  4. unit PrintStuff;                                     { printing unit based on Luke's caring print loop }
  5.  
  6. interface
  7. uses
  8.     PrintTraps;
  9.  
  10. function Print (thePrRecHdl: THPrint): boolean;
  11. function PageSetup (thePrRecHdl: THPrint): boolean;
  12.  
  13. implementation
  14.  
  15. type
  16.  
  17.     heightAndWidth = record
  18.             height: integer;
  19.             width: integer;
  20.         end;
  21. var
  22.     theStatus: TPrStatus;
  23.     pageDims: heightAndWidth;
  24.     documentPicture: PicHandle;
  25.  
  26.  
  27. procedure AlertUser (rTheAlert: integer);
  28. EXTERNAL;
  29.  
  30. function GetPages (theDocBounds: Rect; thePrintRecord: THPrint): heightAndWidth;
  31.     var
  32.         pageLength, docLength, height, width: integer;
  33.  
  34. { Note that we'll use these "length" variables twice -- once for the width, and once for the height. }
  35. { They're just one-dimensional, so why use stack space to declare two copies? }
  36.  
  37.     begin
  38.         with theDocBounds do
  39.             docLength := right - left;
  40.         with thePrintRecord^^.prInfo.rPage do
  41.             pageLength := right - left;
  42.  
  43.         width := docLength div pageLength;
  44.         if docLength mod pageLength <> 0 then
  45.             width := width + 1;
  46.  
  47.         with theDocBounds do
  48.             docLength := bottom - top;
  49.         with thePrintRecord^^.prInfo.rPage do
  50.             pageLength := bottom - top;
  51.  
  52.         height := docLength div pageLength;
  53.         if docLength mod pageLength <> 0 then
  54.             height := height + 1;
  55.  
  56.         GetPages.width := width;
  57.         GetPages.height := height;
  58.  
  59.     end;
  60.  
  61. procedure UnLoadTheWorld;  {Nothing here right now for segmentation}
  62.  
  63. {    UnLoadTheWorld will swap out ALL unneeded code segments and data that are NOT required during print time.}
  64. {Your print code must be a separate code segment.  }
  65.  
  66.     begin
  67.     end;
  68.  
  69. function DetermineRealNumberOfPagesInDoc (documentSize: Rect; printRecord: THPrint): integer;
  70.  
  71.     begin
  72.         pageDims := GetPages(documentSize, printRecord);
  73.         DetermineRealNumberOfPagesInDoc := pageDims.height * pageDims.width;
  74.         ;
  75.     end;
  76.  
  77.  
  78. procedure DrawStuff (thePage: rect; thePort: GrafPtr; pageNumber: integer; thePicture: PicHandle);
  79.  
  80.     var
  81.         printingRect: Rect;
  82.         offsetPage: Rect;
  83.  
  84.     begin
  85.  
  86. { We draw pages horizontally first, then vertically, so if there are four pages, page 2 is to the right of page 1. }
  87.  
  88. { First, get the offset rectangle for the page we're drawing }
  89.  
  90.         offsetPage := thePicture^^.picFrame;
  91.         OffsetRect(offsetPage, -((pageNumber - 1) mod pageDims.width) * (thePage.right - thePage.left), -((pageNumber - 1) div pageDims.width) * (thePage.bottom - thePage.top));
  92.         DrawPicture(thePicture, offsetPage);
  93.  
  94.     end;
  95.  
  96. procedure MyPIdleProcedure;
  97.     var
  98.         pIdleEventRecord: EventRecord;
  99.     begin
  100.         if GetNextEvent(keyDownMask, pIdleEventRecord) then
  101.             begin
  102.                 if ((BitAnd(pIdleEventRecord.message, charCodeMask) = longint('.')) and (BitAnd(longint(pIdleEventRecord.modifiers), cmdKey) = cmdKey)) then
  103.                     PrSetError(iPrAbort);
  104.             end;
  105.     end;
  106.  
  107.  
  108. function PageSetup (thePrRecHdl: THPrint): boolean;
  109.  
  110.     var
  111.         PrintError: LongInt;
  112.         oldPort: GrafPtr;
  113.         printmgrsResFile: integer;
  114.  
  115.     begin
  116.         GetPort(oldPort);
  117.         printmgrsResFile := CurResFile;
  118.         if thePrRecHdl <> nil then
  119.             begin
  120.                 PrOpen;
  121.                 if (PrError = noErr) then
  122.                     begin
  123.                         if (PrError = noErr) then
  124.                             begin
  125.                                 if (PrStlDialog(thePrRecHdl)) then
  126.                 { Do any post-processing on the style dialog results you need to here }
  127.                                 else
  128.                                     PrSetError(iPrAbort);   {**  Cancel from the style dialog  **}
  129.                             end;
  130.                     end;
  131.                 PrintError := PrError;
  132.  
  133.                 PrClose;
  134.  
  135.                                             {**}
  136. {                                            You do not want to report any printing errors}
  137. {                                            until you}
  138. {                                            have fallen through the printing loop . This will make sure that ALL of the Print Manager 's open calls have their corresponding close calls, thereby}
  139. {                                            enabling the Print Manager to close properly and that all temporary memory allocations are released . * *}
  140.  
  141.                 if (PrintError <> noErr) and (PrintError <> iPrAbort) then
  142.  { PostPrintingErrors(PrintError); Need to add this }
  143.             end;
  144.  
  145.         UseResFile(printmgrsResFile);
  146.         SetPort(oldPort);
  147.  
  148.     end; {PageSetup}
  149.  
  150. function Print (thePrRecHdl: THPrint): boolean;
  151.  
  152.     var
  153.         copies, firstPage, lastPage, loop, numberOfCopies, pageNumber, printmgrsResFile, dummyFlags, realNumberOfPagesInDoc: Integer;
  154.         PrintError: LongInt;
  155.         oldPort: GrafPtr;
  156.         thePrPort: TPPrPort;
  157. {theStatus: TPrStatus;}
  158.         PrintingStatusDialog: DialogPtr;
  159.         documentBounds: Rect;
  160.  
  161.     begin
  162.         GetPort(oldPort);
  163.         PrintingStatusDialog := nil;
  164.  
  165.     {**}
  166.         UnLoadTheWorld;
  167.  
  168.         if (MemError = noErr) and (thePrRecHdl <> nil) then
  169.             begin
  170.                 PrOpen;
  171.                 if (PrError = noErr) then
  172.                     begin
  173.  
  174. {                    Save the current resource file ( i . e . the printer driver's) so the driver will not lose its resources}
  175. {                    upon return from the pIdleProc.  }
  176.  
  177.                         printmgrsResFile := CurResFile;
  178.  
  179.                         if (PrError = noErr) then
  180.                             begin
  181.                                     {**}
  182. {                                    DetermineNumberOfPagesinDoc determines the number of pages contained in the document by comparing the size of the document}
  183. {                                    with rPage from the TPrInfo}
  184. {                                    record}
  185. {                                            ( IM II - 150 ) . It returns the number of pages required to print the document}
  186. {                                            for the currently selected printer . * *}
  187.  
  188.                                 documentPicture := GetPicture(256);
  189.                                 documentBounds := documentPicture^^.picFrame;
  190.                                 realNumberOfPagesinDoc := DetermineRealNumberOfPagesinDoc(documentBounds, thePrRecHdl);
  191.                                 ;
  192.  
  193.                                 if PrJobDialog(thePrRecHdl) then
  194.                                     begin
  195.  
  196. {                                                  Get the number of copies of the document that the user wants printed from iCopies of the TPrJob }
  197. {                                                    record}
  198. {                                                            ( IM II - 151 ) . * *}
  199.  
  200.                                         numberOfCopies := thePrRecHdl^^.prJob.iCopies;
  201.  
  202. {                                                            Get the first and last pages of the document that were requested to be printed by the user from iFstPage and iLastPage from the TPrJob}
  203. {                                                            record}
  204. {                                                                    ( IM II - 151 ) . * *}
  205.  
  206.                                         firstPage := thePrRecHdl^^.prJob.iFstPage;
  207.                                         lastPage := thePrRecHdl^^.prJob.iLstPage;
  208.  
  209. {                                                                    Print "}
  210. {                                                                    all "}
  211. {                                                                    pages in the print loop * *}
  212.  
  213.                                         thePrRecHdl^^.prJob.iFstPage := 1;
  214.                                         thePrRecHdl^^.prJob.iLstPage := 9999;
  215.  
  216. {                                                                    Determine the "}
  217. {                                                                    real "}
  218. {                                                                    number of pages contained in the document . Without this test , you would print 9999 pages . * *}
  219.  
  220.                                         if (realNumberOfPagesinDoc < lastPage) then
  221.                                             lastPage := realNumberOfPagesinDoc;
  222.  
  223.                                         PrintingStatusDialog := GetNewDialog(257, nil, POINTER(-1));
  224.  
  225.                                                                     {**}
  226. {                                                                    Print the number of copies of the document requested by the user from the Print Job Dialog . * *}
  227.  
  228.                                         for copies := 1 to numberOfCopies do
  229.                                             begin
  230.  
  231.                                                                             {**}
  232. {                                                                            Install a pointer to your pIdle proc in my print}
  233. {                                                                            record}
  234. {                                                                                    . * *}
  235.                                                 thePrRecHdl^^.prJob.pIdleProc := @MyPIdleProcedure;
  236.  
  237.                                                                                     {**}
  238. {                                                                                    Restore the resource}
  239. {                                                                                    file to the printer driver 's.}
  240. {                                                                                    * *}
  241.                                                 UseResFile(printmgrsResFile);
  242.  
  243.                                                 thePrPort := PrOpenDoc(thePrRecHdl, nil, nil);
  244.  
  245.                                                 SetPort(GrafPtr(thePrPort));
  246.  
  247.                                                 if (PrError = noErr) then
  248.                                                     begin
  249.                                                                                             {**}
  250. {                                                                                            Print the range of pages of the document requested by the user from the Print Job Dialog . * *}
  251.                                                         pageNumber := firstPage;
  252.                                                         while ((pageNumber <= lastPage) and (PrError = noErr)) do
  253.                                                             begin
  254.  
  255.                                                                 PrOpenPage(thePrPort, nil);
  256.  
  257.                                                                 if (PrError = noErr) then
  258.                                                                     begin
  259.                                                                                                             {**}
  260. {                                                                                                            rPage ( IM II - 150 ) is the printable area}
  261. {                                                                                                            for the currently selected printer . By passing the current enables your app to use the same routine to draw to the screen and the printer 's GrafPort.}
  262. {                                                                                                            * *}
  263.  
  264.                                                                         DrawStuff(thePrRecHdl^^.prInfo.rPage, GrafPtr(thePrPort), pageNumber, documentPicture);
  265.                                                                     end;
  266.                                                                 PrClosePage(thePrPort);
  267.                                                                 pageNumber := pageNumber + 1;
  268.                                                             end;  {**  End pagenumber loop  **}
  269.                                                     end;
  270.                                                 PrCloseDoc(thePrPort);
  271.                                             end; {**  End copies loop  **}
  272.  
  273.                                                                             {**}
  274. {                                                                            The printing job is being canceled by the request of the user from the Print Style Dialog or the Print Job Dialog . PrError will be}
  275. {                                                                            set to iPrAbort to tell the Print Manager to abort the current printing job . * *}
  276.                                     end
  277.                                 else
  278.                                     PrSetError(iPrAbort);   {**  Cancel from the job dialog  **}
  279.                             end;
  280.                     end;
  281.                 if (thePrRecHdl^^.prJob.bJDocLoop = bSpoolLoop) and (PrError = noErr) then
  282.                     PrPicFile(thePrRecHdl, nil, nil, nil, theStatus);
  283.  
  284.                                             {**}
  285. {                                            Grab the printing error before you close the Print Manager and the error disappears . * *}
  286.  
  287.                 PrintError := PrError;
  288.  
  289.                 PrClose;
  290.  
  291.                                             {**}
  292. {                                            You do not want to report any printing errors}
  293. {                                            until you}
  294. {                                            have fallen through the printing loop . This will make sure that ALL of the Print Manager 's open calls have their corresponding close calls, thereby}
  295. {                                            enabling the Print Manager to close properly and that all temporary memory allocations are released . * *}
  296.  
  297.                 if (PrintError <> noErr) then
  298.  { PostPrintingErrors(PrintError); Need to add this }
  299.  
  300.             end;
  301.  
  302.         if (PrintingStatusDialog <> nil) then
  303.             DisposDialog(PrintingStatusDialog);
  304.  
  305.         SetPort(oldPort);
  306.     end;  {**  print stuff  **}
  307. end.